<!-- src/components/CommentModal.vue -->
<template>
  <Teleport to="body">
    <Transition name="modal-fade-up">
      <div v-if="model" class="comment-modal-overlay" @click.self="close">
        <div class="comment-modal" :class="{ 'scaleH': modalScale }">
          <!-- 头部 -->
          <div class="comment-header">
            <h3 class="comment-count">{{ comments.length }}条评论</h3>
            <button class="zoom-btn" @click="zoom">
              <Icon :name="modalScale ? 'suoxiao' : 'fangda'" color="#999" size="16" />
            </button>
            <button class="close-btn" @click="close">x</button>
          </div>

          <!-- 评论列表 -->
          <div class="comment-list" @scroll="handleScroll" ref="commentListRef">
            <div v-if="initialLoading" class="initial-loading">
              <div class="loading-icon">
                <Icon name="jiazailoadding" color="#999" size="24" />
              </div>
            </div>
            <!-- 空状态提示 -->
            <div v-if="!loadingMore && comments.length === 0" class="no-comments-placeholder">
              <Icon name="pinglun" color="#ccc" size="30" />
              <p class="placeholder-text">暂无更多数据，快评论吧～</p>
            </div>
            <div class="comment-item" v-for="comment in comments" :key="comment.commentId">
              <img :src="comment.userAvatar" alt="avatar" class="avatar" />
              <div class="comment-body">
                <span class="username">{{ comment.userNickname }}</span>

                <!-- 文字评论 -->
                <p v-if="!comment.isImageComment" class="content">{{ comment.commentContent }}</p>

                <!-- 图片评论 -->
                <div v-else class="image-comment">
                  <img :src="comment.imageUrl" alt="评论图片" class="comment-image" />
                  <p v-if="comment.commentContent !== '分享了一张图片'" class="image-caption">{{ comment.commentContent }}</p>
                </div>

                <div class="actions">
                  <span class="time">{{ comment.formattedTime }}</span>
                  <button @click="() => onReply(comment.userNickname)" class="action-btn">
                    <Icon name="reply" color="#999" size="16" />
                    <span>回复</span>
                  </button>
                  <div class="like-btn" @click="likeComment(comment.commentId)">
                    <Icon name="xin-2" :color="comment.isLiked ? 'red' : '#ccc'" size="16" />
                    <span>{{ comment.likeNum }}</span>
                  </div>
                </div>
              </div>
            </div>
            <!-- 加载中提示 -->
            <div v-if="loadingMore && hasMore" class="loading-more">加载中...</div>
            <div v-else-if="!hasMore && comments.length > 0" class="no-more">没有更多评论了</div>
          </div>
          <!-- 隐藏的文件选择器 -->
          <input ref="fileInputRef" type="file" accept="image/*" style="display: none" @change="handleImageSelect" />
          <!-- 输入框 -->
          <div class="input-area">
            <input v-model="inputValue" ref="inputRef" type="text"
              :placeholder="selectedImage ? '可添加图片描述（可选）' : '说点什么吧...'" @input="handleInput"
              @keydown.enter.prevent="submitComment" />
            <div class="image-btn" @click="triggerFileInput">
              <Icon name="tupian" color="#000" size="18" />
            </div>
            <div class="friend-btn" @click="showFriendList = true">
              <Icon name="aite" color="#000" size="18" />
            </div>
            <div class="send-btn" @click="submitComment">
              <Icon name="dui" color="#000" size="18" />
            </div>

            <!-- 图片预览区（仅当有图时显示） -->
            <div v-if="selectedImage" class="image-preview">
              <img :src="selectedImage" alt="预览" />
              <button class="remove-preview" @click.stop="clearImagePreview">×</button>
            </div>
          </div>
        </div>
      </div>
    </Transition>
    <Transition name="modal-fade-up">
      <FriendList v-if="showFriendList" v-model="showFriendList" @postselectUser="handlePostselectUser" />
    </Transition>
  </Teleport>
</template>

<script setup>
import { formatTimeAgo } from '@/utils/time'
import { ref, watch, defineAsyncComponent, inject } from 'vue'
import Icon from '@/components/common/Icon.vue'
import { getCommentAPI, getCommentLikeStatusAPI, postCommentAPI, likeCommentAPI, friendRequestAPI } from '@/api/getcomment'
import { Toast } from '@/utils/showtoast'
import { checkSensitiveWords } from '@/api/content.js'
import { useUserStore } from '@/stores/userinfo'
const socket = inject('socket')

const userStore = useUserStore()
const { userId, userNickname, userAvatar } = userStore.userInfo

const props = defineProps({
  videoId: { type: String, default: '' }
})

const model = defineModel()
const comments = ref([])
const currentPage = ref(0)
const hasMore = ref(true)
const loadingMore = ref(false)
const commentListRef = ref(null)
const initialLoading = ref(true)
const inputValue = ref('')
const inputRef = ref(null)
const modalScale = ref(false)
const showFriendList = ref(false)
const fileInputRef = ref(null)
const selectedImage = ref(null) // 用于存储选中的图片预览 URL
const FriendList = defineAsyncComponent(() => import('@/components/common/FriendList.vue'))

// ========================
// 加载某一页评论
// ========================
const loadPage = async (page) => {
  try {
    const res = await getCommentAPI(props.videoId, page)
    return res.data || []
  } catch (error) {
    console.warn(`page ${page} 请求失败:`, error)
    return null
  }
}

// ========================
// 首次加载评论（尝试 page 1~3）
// ========================
const loadInitialComments = async () => {
  initialLoading.value = true
  let rawData = []
  let success = false

  for (const page of [1, 2, 3]) {
    const data = await loadPage(page)
    if (data !== null) {
      rawData = data
      currentPage.value = page
      success = true
      break
    }
  }

  if (!success) {
    comments.value = []
    hasMore.value = false
  } else {
    await processComments(rawData, true)
  }

  initialLoading.value = false
}

// ========================
// 处理评论数据：每次都重新获取点赞状态（无缓存）
// ========================
const processComments = async (rawData, isInitial = false) => {
  if (!rawData.length) {
    hasMore.value = false
    return
  }

  const commentIds = rawData.map(item => item.Comment.commentId)

  // 每次都重新请求点赞状态（不缓存）
  const likeStatusPromises = commentIds.map(id =>
    getCommentLikeStatusAPI(userId, id)
      .then(res => ({ id, isLiked: res.data }))
      .catch(() => ({ id, isLiked: false }))
  )

  const likeStatuses = await Promise.all(likeStatusPromises)
  const likeStatusMap = new Map(likeStatuses.map(s => [s.id, s.isLiked]))

  const processed = rawData.map(item => {
    const avatar = item.Comment.userAvatar || '/assets/avatar/default.png'
    return {
      ...item.Comment,
      likeNum: Number(item.likeNum) || 0,
      userAvatar: 'http://43.138.15.137:3000' + avatar,
      isLiked: likeStatusMap.get(item.Comment.commentId) ?? false,
      createdAt: item.Comment.createdAt,
      formattedTime: formatTimeAgo(item.Comment.createdAt),
      commentId: item.Comment.commentId
    }
  })

  comments.value = isInitial ? processed : [...comments.value, ...processed]
}

// ========================
// 加载更多
// ========================
const loadMoreComments = async () => {
  if (!hasMore.value || loadingMore.value) return

  const nextPage = currentPage.value + 1
  loadingMore.value = true
  const rawData = await loadPage(nextPage)
  loadingMore.value = false

  if (rawData === null || rawData.length === 0) {
    hasMore.value = false
    return
  }

  currentPage.value = nextPage
  await processComments(rawData, false)
}

// ========================
// 滚动到底部加载更多
// ========================
const handleScroll = () => {
  const el = commentListRef.value
  if (!el) return
  const { scrollTop, scrollHeight, clientHeight } = el
  if (scrollTop + clientHeight >= scrollHeight - 10) {
    loadMoreComments()
  }
}

// ========================
// 监听 videoId 变化
// ========================
watch(() => props.videoId, (newId) => {
  if (newId) {
    // 重置状态
    comments.value = []
    currentPage.value = 0
    hasMore.value = true
    loadingMore.value = false
    inputValue.value = ''

    // 清理选中的图片
    if (selectedImage.value) {
      URL.revokeObjectURL(selectedImage.value)
      selectedImage.value = null
    }

    // 加载新视频的评论
    loadInitialComments()
  }
}, { immediate: true })

// ========================
// 交互方法
// ========================
const close = () => {
  model.value = false
  // 清理输入内容
  inputValue.value = ''
  // 清理选中的图片
  if (selectedImage.value) {
    URL.revokeObjectURL(selectedImage.value)
    selectedImage.value = null
  }
}
const submitComment = async () => {
  const originalInput = inputValue.value.trim()
  const hasImage = !!selectedImage.value

  // 如果既没有文字也没有图片，直接返回
  if (!originalInput && !hasImage) return

  // 🚨【敏感词检测】统一处理要提交的文本内容
  const contentToCheck = originalInput || '分享了一张图片'
  try {
    const checkResult = await checkSensitiveWords(contentToCheck)
    if (!checkResult.safe) {
      // 提示用户（你可以换成 ElMessage、Toast 等）
      // alert(`内容包含敏感词：${checkResult.keywords.join(', ')}`)
      Toast(`内容包含敏感词:${checkResult.keywords.join(', ')},请输入温柔的话吧~`)
      return // 阻止提交
    }
  } catch (error) {
    console.warn('敏感词检测异常，为安全起见，阻止提交', error)
    alert('内容安全检查失败，请稍后再试')
    return
  }

  // ==============================
  // 情况1：有选中图片 → 模拟图片评论（前端展示）
  // ==============================
  if (hasImage) {
    const mockComment = {
      commentId: 'mock-' + Date.now(),
      commentContent: contentToCheck, // 使用已检测过的内容
      userAvatar,
      userNickname,
      likeNum: 0,
      isLiked: false,
      formattedTime: '刚刚',
      createdAt: new Date().toISOString(),
      videoId: props.videoId,
      userId,
      isImageComment: true,
      imageUrl: selectedImage.value
    }

    comments.value.unshift(mockComment)

    // 重置状态
    if (selectedImage.value) {
      URL.revokeObjectURL(selectedImage.value)
    }
    selectedImage.value = null
    inputValue.value = ''
    return
  }

  // ==============================
  // 情况2：纯文字评论 → 调用真实 API
  // ==============================
  const data = {
    content: originalInput,
    toVideoId: props.videoId,
    replyId: '',
    fromUserId: userId,
  }

  const containsMention = originalInput.includes('@')
  const originalFriendUserId = friendUserId.value // 备份，防止异步变化

  try {
    // 先清空输入框，提供即时反馈
    inputValue.value = ''

    const res = await postCommentAPI(data)
    const newComment = res.data

    // 如果包含 @，发送好友请求
    if (containsMention && originalFriendUserId) {
      await friendRequestAPI(userId, {
        commentId: newComment.commentId,
        userIdStr: originalFriendUserId,
        videoId: newComment.videoId,
      })

      socket.emit('sendFriend', {
        commentId: newComment.commentId,
        userIdStr: originalFriendUserId,
        videoId: newComment.videoId,
      })
    }

    // 构造前端展示用的评论对象
    const normalizedComment = {
      commentId: newComment.commentId,
      commentContent: newComment.commentContent,
      commentReplyID: newComment.commentReplyID || '',
      createdAt: newComment.createdAt,
      userId: newComment.userId,
      videoId: newComment.videoId,
      userAvatar,
      userNickname,
      likeNum: 0,
      isLiked: false,
      formattedTime: formatTimeAgo(newComment.createdAt)
    }

    // 添加到顶部
    comments.value.unshift(normalizedComment)

    // 通知 WebSocket
    socket.emit('sendComment', {
      toVideoId: props.videoId,
      replyId: ''
    })
  } catch (error) {
    // 提交失败，恢复输入内容
    inputValue.value = originalInput
    console.warn('评论提交失败:', error)
    alert('评论发送失败，请重试')
  }
}
const handleInput = (e) => {
  if (e.target.value.includes('@')) {
    showFriendList.value = true;
  }
}

const onReply = (username) => {
  inputValue.value = `@${username} `
  inputRef.value?.focus()
}

const zoom = () => { modalScale.value = !modalScale.value }
// 好友 Id 储存
const friendUserId = ref('')
const handlePostselectUser = (user) => {
  console.log('好友userId', user.userId)
  friendUserId.value = user.userId
  inputValue.value += `@${user.userNickname} `
  inputRef.value?.focus()
}

// ========================
// 点赞逻辑（乐观更新）
// ========================
const likeComment = async (commentId) => {
  const comment = comments.value.find(c => c.commentId === commentId)
  if (!comment) return

  // 乐观更新：先切换状态
  const wasLiked = comment.isLiked
  comment.isLiked = !wasLiked
  comment.likeNum += wasLiked ? -1 : 1

  try {
    await likeCommentAPI(userId, props.videoId, commentId)
    // 成功：状态已更新，无需操作
  } catch (error) {
    // 失败：回滚状态
    console.warn('点赞失败，回滚状态:', error)
    comment.isLiked = wasLiked
    comment.likeNum += wasLiked ? 1 : -1
  }
}

// 触发隐藏 input 点击
const triggerFileInput = () => {
  fileInputRef.value?.click()
}

// 修改 handleImageSelect
const handleImageSelect = (event) => {
  const file = event.target.files?.[0]
  if (!file) return

  // 生成本地预览 URL
  selectedImage.value = URL.createObjectURL(file)
  // inputValue.value = '' // 清空文字（可选，你也可以保留文字+图片）
  event.target.value = ''
}
// 清除图片预览
const clearImagePreview = () => {
  if (selectedImage.value) {
    URL.revokeObjectURL(selectedImage.value) // 释放内存
  }
  selectedImage.value = null
}

</script>

<style lang="scss" scoped>
.comment-modal-overlay {
  @include fixed-top;
  width: 100vw;
  height: 100vh;
  background: rgba(0, 0, 0, 0.6);
  @include flex-center;
  align-items: flex-end;
  z-index: 10000;

  .comment-modal {
    width: 100%;
    max-width: 500px;
    background: $white-color;
    border-radius: 16px 16px 0 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    height: 70%;
    transition: transform 0.3s ease, height 0.3s ease; // 保留 transition

    &.scaleH {
      height: 100%;
    }

    .comment-header {
      color: $bg-color;
      @include flex-center;
      border-bottom: 1px solid$comment-modal-border-color;
      position: relative;
      padding: 10px 0;

      .comment-count {
        font-size: 14px;
      }

      .zoom-btn {
        width: 22px;
        height: 22px;
        @include absolute-top-right(8px, 44px);
        border-radius: $border-radius-full;
        background-color: #efefef;
      }

      .close-btn {
        width: 22px;
        height: 22px;
        background-color: #efefef;
        border-radius: $border-radius-full;
        @include absolute-top-right(8px, 8px);
        @include flex-center;
        color: $border-color;
        font-size: $font-size-base;

      }
    }

    .comment-list {
      flex: 1;
      overflow-y: auto;
      padding: 0 12px;

      &::-webkit-scrollbar {
        display: none
      }

      .comment-item {
        @include flex-center;
        padding: 14px 0 6px;

        .avatar {
          width: 40px;
          height: 40px;
          border-radius: 50%;
          margin-right: 12px;
          align-self: flex-start;
        }

        .comment-body {
          flex: 1;
          padding-bottom: 10px;

          .username {
            font-weight: bold;
            color: $black-color;
          }

          .content {
            width: 80%;
            max-width: 80%; // 防止超出父容器
            color: $black-color;
            margin-bottom: 8px;
            @include multi-line-ellipsis(3);
            line-height: 1.4;
            box-sizing: border-box; // 确保 padding/border 不影响宽度
            word-break: break-all; // 允许在任意字符处换行
            overflow-wrap: break-word; // 也支持长单词断行
          }

          .actions {
            display: flex;
            gap: 16px;

            .like-btn {
              @include flex-center;
              gap: 4px;
              margin-left: auto
            }

            .time {
              color: $text-color;
              font-size: 12px;
            }

            .action-btn {
              @include flex-center;
              background: none;
              border: none;
              color: #999;
              font-size: 14px;
              cursor: pointer;
            }


          }
        }
      }

      .loading-more,
      .no-more {
        text-align: center;
        padding: 12px;
        color: #999;
        font-size: 14px;
      }

      .no-comments-placeholder {
        height: 100%;
        @include flex-center;
        flex-direction: column;
        gap: 12px;
        color: #999;
        font-size: 14px;
      }

      /* style 中 */
      .initial-loading {
        display: flex;
        align-items: center;
        justify-content: center;
        height: 100%;

        .loading-icon {
          animation: rotate 1s linear infinite;
        }
      }

      @keyframes rotate {
        to {
          transform: rotate(360deg);
        }
      }

    }

    .input-area {
      padding: 10px;
      border-top: 1px solid $comment-modal-border-color;
      @include flex-between;
      gap: 8px;
      position: relative;

      &>input {
        flex: 1;
        padding: 12px;
        border-radius: 20px;
        background: #e8e8e9;
        color: #000;
      }

      // 图片
      .image-btn {
        @include absolute-top-right(50%, 80px);
        @include flex-center;
        width: 20px;
        height: 20px;
        border-radius: $border-radius-full;
        transform: translateY(-50%);
      }


      // 好友按钮
      .friend-btn {
        @include absolute-top-right(50%, 50px);
        @include flex-center;
        width: 20px;
        height: 20px;
        border-radius: $border-radius-full;
        transform: translateY(-50%);
      }

      // 发送按钮
      .send-btn {
        @include absolute-top-right(50%, 20px);
        @include flex-center;
        width: 20px;
        height: 20px;
        transform: translateY(-50%);

        border-radius: $border-radius-full;
      }

      .image-preview {
        @include absolute-bottom-left(52px, 12px);
        width: 70px;
        height: 70px;
        border-radius: $border-radius-md;
        overflow: hidden;
        box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
      }

      .remove-preview {
        @include absolute-top-right;
        width: 20px;
        height: 20px;
        border-radius: $border-radius-full;
        background: $red-color;
        color: $white-color;
        border: 2px solid $white-color;
        font-size: $font-size-small;
        cursor: pointer;
        @include flex-center;
      }
    }
  }
}

.image-comment {
  margin-top: 4px;
}

.comment-image {
  max-width: 100%;
  max-height: 200px;
  border-radius: 8px;
  object-fit: cover;
}

.image-caption {
  margin-top: 6px;
  font-size: 14px;
  color: #666;
}
</style>